//
// @Author: zhengqi Wu
// @Description:
// @Version: 1.0.0
// @Date: 2021/3/14 14:08
// @Copyright: MIN-Group；国家重大科技基础设施——未来网络北大实验室；深圳市信息论与未来网络重点实验室
//

const encoding = require('../encoding')
const Identifier = require('./Identifier').Identifier
const {TlvComponentBase} = require('./TlvComponentBase')
var aggregation = require('../common/aggregation')//实现了多继承

class KeyLocator extends aggregation(TlvComponentBase,encoding.SelfEncodingBase){
    constructor() {
        super();
        this.identifier = new Identifier()
    }

    /**
     * @description 获取用于签名的证书或公钥的标识名（指示了位置）
     * @returns {Identifier}
     */
    getIdentifier(){
        return this.identifier
    }

    /**
     * @description 判断当前 KeyLocator 是否有效
     * @returns {boolean}
     */
    isValid(){
        return this.identifier.isValid()
    }

    /**
     * @description 将 KeyLocator 线速编码为 TLV
     * @returns {number}
     */
    wireEncode(enc){
        let totalLength = 0
        try{
            // 编码TLV-VALUE
            let tmpLen = this.identifier.wireEncode(enc)
            // DONE 错误处理
            totalLength += tmpLen

            // 编码TLV-LENGTH
            tmpLen = enc.prependVarNumber((totalLength))
            // DONE 错误处理
            totalLength += tmpLen

            // 编码 TLV-TYPE
            tmpLen = enc.prependVarNumber((encoding.tlv.ComponentType.TlvKeyLocator))
            // DONE 错误处理
            totalLength += tmpLen

            return totalLength
        }catch (e){
            throw e
        }

    }

    /**
     * @description 从 TLV Block 中解码出一个 KeyLocator
     * @param block
     */
    wireDecode(block){
        // 检查 Type 是否正确
        // getType => vlint
        try{
            if(encoding.tlv.expectType(block.getType(), (encoding.tlv.ComponentType.TlvKeyLocator))){
                // 解析子组件
                block.parseSubElements()
                let elements = block.getSubElements()
                if(elements.length === 1){
                    // 解析子 TLV 为一个Identifier
                    this.identifier.wireDecode(elements[0])
                }
            }
        }catch (e){
            throw e
        }

    }

    /**
     * @description 根据一个 TVL Block 初始化当前 KeyLocator
     * @param block
     */
    buildKeyLocatorByBlock(block){
        try{
            this.wireDecode(block)
        }catch (e){
            throw e
        }

    }

    /**
     * @description 根据一个标识字符串初始化当前 KeyLocator
     * @param identifierString
     */
    buildKeyLocatorByString(identifierString){
        try{
            this.identifier.buildIdentifierByString(identifierString)
        }catch (e){
            throw e
        }
    }

    /**
     * @description 根据 components 初始化当前 KeyLocator
     * @param container
     */
    buildKeyLocatorByComponents(container){
        try{
            this.identifier.buildIdentifierByComponents(container)
        }catch (e){
            throw e
        }
    }

    /**
     * @description 根据 Identifier 初始化当前 KeyLocator
     * @param identifier
     */
    buildKeyLocatorByIdentifier(identifier){
        try{
            this.identifier.buildIdentifierByComponents(identifier.components)
        }catch (e){
            throw e
        }

    }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
///// 构造函数 Create*
/////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * @description 根据一个 TLV Block 创建一个 KeyLocator
 * @param block
 * @returns {KeyLocator}
 */
function createKeyLocatorByBlock(block) {
    try{
        let keyLocator = new KeyLocator()
        keyLocator.buildKeyLocatorByBlock(block)
        return keyLocator
    }catch (e){
        throw e
    }

}

/**
 * @description 根据标识字符串 创建一个 KeyLocator
 * @param identifierString
 * @returns {KeyLocator}
 */
function createKeyLocatorByString(identifierString) {
    try{
        let keyLocator = new KeyLocator()
        keyLocator.buildKeyLocatorByString(identifierString)
        return keyLocator
    }catch (e){
        throw e
    }

}

/**
 * @description 根据 components 创建一个 KeyLocator
 * @param container
 * @returns {KeyLocator}
 */
function createKeyLocatorByComponents(container) {
    try{
        let keyLocator = new KeyLocator()
        keyLocator.buildKeyLocatorByComponents(container)
        return keyLocator
    }catch (e){
        throw e
    }

}

/**
 * @description 根据 Identifier 创建一个 KeyLocator
 * @param identifier
 * @returns {KeyLocator}
 */
function createKeyLocatorByIdentifier(identifier) {
    try{
        let keyLocator = new KeyLocator()
        keyLocator.buildKeyLocatorByIdentifier(identifier)
        return keyLocator
    }catch (e){
        throw e
    }

}

module.exports = {
    KeyLocator:KeyLocator,
    createKeyLocatorByBlock: createKeyLocatorByBlock,
    createKeyLocatorByString: createKeyLocatorByString
}